home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 43 / Amiga Format CD43 (1999)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-09].iso / -serious- / archivers / xpk / xpk_source / shell / xdir.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  5KB  |  216 lines

  1. #define NAME        "xDir"
  2. #define DISTRIBUTION    "(Freeware) "
  3. #define REVISION    "6"
  4.  
  5. /* Programmheader
  6.  
  7.     Name:        xDir
  8.     Author:        SDI (before 1.2 Urban Dominik Müller)
  9.     Distribution:    Freeware
  10.     Description:    xpk file lister
  11.     Compileropts:    -
  12.     Linkeropts:    -l xpkmaster
  13.  
  14.  1.0    : first public release
  15.  1.1    : Enforcer hit fixed, version string added, wrote documentation
  16.  1.2   29.11.96 : reworked for new includes
  17.  1.3   24.04.97 : fixed lots of errors, made a lot shorter, easier
  18.  1.4   12.07.97 : totally rewritten
  19.  1.5   27.97.97 : little fixes
  20.  1.6   10.03.98 : new ASM_STD includes, uses xfdmaster for checks always
  21. */
  22.  
  23. #include "SDI_defines.h"
  24. #define SDI_TO_ANSI
  25. #include "SDI_ASM_STD_protos.h"
  26. #include <proto/exec.h>
  27. #include <proto/dos.h>
  28. #include <proto/xpkmaster.h>
  29. #include <exec/memory.h>
  30.  
  31. struct DataList {
  32.   struct DataList *    next;
  33.   UWORD            size; /* size of complete list */
  34.   UBYTE             text[0]; /* text data, which follows the structure */
  35. };
  36.  
  37. #define TEXTSIZE    40
  38.  
  39. struct Library *XpkBase = 0;
  40.  
  41. ULONG exitem(STRPTR, ULONG *, ULONG *);
  42. ULONG exfile(struct FileInfoBlock *, struct DataList *, ULONG *, ULONG *);
  43.  
  44. void main(int argc, char *argv[])
  45. {
  46.   ULONG ret = 20;
  47.  
  48.   if(argc == 2 && argv[1][0] == '?')
  49.   {
  50.     printf("Usage: xDir files/dirs\n"); exit(10);
  51.   }
  52.  
  53.   if((XpkBase = OpenLibrary(XPKNAME, 3)))
  54.   {
  55.     ULONG utot = 0, ctot = 0;
  56.  
  57.     printf("Original  Packed  Ratio Type Protection Name\n"
  58.     "-------- -------- ----- ---- ---------- ----\n");
  59.  
  60.     if(argc == 1)
  61.       ret = exitem("", &utot, &ctot);
  62.     else
  63.     {
  64.       ULONG i = 1;
  65.       while(i < argc && !(ret = exitem(argv[i], &utot, &ctot)))
  66.       {
  67.         if(++i < argc)
  68.           printf("\n");
  69.       }
  70.     }
  71.  
  72.     if(!ret)
  73.       printf("-------- -------- -----\n%8ld %8ld  %2ld%%\n", utot, ctot,
  74.       (utot && (utot > ctot)) ? 100 - (100 * ctot) / utot : 0);
  75.   }
  76.   else
  77.     printf("Cannot open xpkmaster.library\n");
  78.  
  79.   if(CTRL_C)
  80.     printf(" *** Break\n");
  81.  
  82.   exit(ret);
  83. }
  84.  
  85. ULONG exitem(STRPTR name, ULONG *utot, ULONG *ctot)
  86. {
  87.   BPTR lock;
  88.   ULONG ret = 20;
  89.  
  90.   if((lock = Lock(name, ACCESS_READ)))
  91.   {
  92.     struct FileInfoBlock *fib;
  93.  
  94.     if((fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), MEMF_ANY)))
  95.     {
  96.       if(Examine(lock, fib))
  97.       {
  98.         struct DataList *list, *d, in = {0,0};
  99.  
  100.     list = ∈
  101.  
  102.         if(fib->fib_DirEntryType < 0)
  103.         {
  104.       BPTR prev;
  105.           name[strlen(name)-strlen(fib->fib_FileName)] = 0; /* cut the filename */
  106.           UnLock(lock);
  107.           if((lock = Lock(name, ACCESS_READ)))
  108.           {
  109.         prev = CurrentDir(lock);
  110.             ret = exfile(fib, list, utot, ctot);
  111.         CurrentDir(prev);
  112.       }
  113.       else
  114.         printf("Error locking %s\n", name);
  115.     }
  116.     else
  117.     {
  118.       BPTR prev;
  119.  
  120.       prev = CurrentDir(lock);
  121.       while(ExNext(lock, fib) && !(ret = exfile(fib, list, utot, ctot)))
  122.         ;
  123.       CurrentDir(prev);
  124.     }
  125.  
  126.     list = list->next; /* skip init entry */
  127.  
  128.     if(!ret)
  129.     {
  130.       for(d = list; !CTRL_C && d; d = d->next)
  131.         printf("%s", d->text);
  132.     }
  133.  
  134.     while(list) /* free the list */
  135.     {
  136.       d = list->next;
  137.       FreeMem(list, list->size);
  138.       list = d;
  139.     }
  140.       }
  141.       else
  142.         printf("Error %ld locking %s\n", IoErr(), name);
  143.  
  144.       FreeMem(fib, sizeof(struct FileInfoBlock));
  145.     }
  146.     else
  147.       printf("Not enough memory\n");
  148.  
  149.     if(lock)
  150.       UnLock(lock);
  151.   }
  152.   else
  153.     printf("Error %ld locking %s\n", IoErr(), name);
  154.  
  155.   return ret;
  156. }
  157.  
  158. ULONG exfile(struct FileInfoBlock *fib, struct DataList *l, ULONG *utot, ULONG *ctot)
  159. {
  160.   struct DataList *dl, *le;
  161.   ULONG listsize, fl;
  162.   struct XpkFib xfib;
  163.   ULONG i, clen = 0, ulen = 0;
  164.  
  165.   fl = strlen(fib->fib_FileName);
  166.   listsize = sizeof(struct DataList) + fl + TEXTSIZE + 2; /* '\n' and '\0' */
  167.  
  168.   if(!(dl = (struct DataList *) AllocMem(listsize, MEMF_ANY|MEMF_CLEAR)))
  169.   {
  170.     printf("Not enough memory\n"); return 20;
  171.   }
  172.  
  173.   memset(dl->text, ' ', 40);
  174.   dl->size = listsize;
  175.  
  176.   if(fib->fib_EntryType >= 0)
  177.     CopyMem("<Dir>", dl->text+3, 5);
  178.   else if(!XpkExamineTags(&xfib, XPK_InName, fib->fib_FileName,
  179.   XPK_UseXfdMaster, TRUE, TAG_DONE)
  180.   && xfib.xf_Type == XPKTYPE_PACKED)
  181.   {
  182.     sprintf(dl->text, "%8ld %8ld  %2ld%%  %4s",
  183.     ulen = xfib.xf_ULen, clen = xfib.xf_CLen, xfib.xf_Ratio,
  184.     xfib.xf_Packer);
  185.     dl->text[28] = ' ';
  186.   }
  187.   else
  188.   {
  189.     sprintf(dl->text, "%8ld", clen = ulen = fib->fib_Size);
  190.     dl->text[8] = ' ';
  191.   }
  192.  
  193.   dl->text[29] = fib->fib_DirEntryType < 0 ? '-' : 'D';
  194.   for(i = 0; i < 8; i++)
  195.     dl->text[37-i] = (fib->fib_Protection ^ 0x0f) & (1 << i) ? "dewrapsh"[i] : '-';
  196.  
  197.   *utot += ulen;
  198.   *ctot += clen;
  199.  
  200.   CopyMem(fib->fib_FileName, dl->text+40, fl);
  201.   dl->text[40+fl] = '\n';
  202.  
  203.   /* sort and insert the new line, skip &in entry first */
  204.   do
  205.   {
  206.     le = l;
  207.     l = l->next;
  208.   } while(l && stricmp(l->text+40, dl->text+40) < 0);
  209.  
  210.   dl->next = l;
  211.   le->next = dl;
  212.  
  213.   return 0;
  214. }
  215.  
  216.